import React, { useState, useEffect, useMemo, useCallback } from 'react';
import {
  Tree,
  Badge,
  Progress,
  Space,
  Typography,
  Tag,
  Tooltip,
  Button,
  Dropdown,
  Menu,
  Input,
  message,
  Spin,
} from 'antd';
import {
  FolderOutlined,
  FolderOpenOutlined,
  FileOutlined,
  BarChartOutlined,
  EyeOutlined,
  EditOutlined,
  SearchOutlined,
  FilterOutlined,
  DownOutlined,
  RightOutlined,
} from '@ant-design/icons';
import type { DataNode, EventDataNode } from 'antd/es/tree';
import { directoryApi } from '../services/api';

const { Text } = Typography;
const { Search } = Input;

export interface BackendDirectoryNode {
  name: string;
  path: string;
  type: 'directory' | 'file';
  level: number;
  metric_count: number;
  file_count: number;
  assigned_teams: string[];
  components: string[];
  metric_types?: Record<string, number>;
  analysis_stats?: Record<string, number>;
  children?: BackendDirectoryNode[];
  metrics?: Array<{
    id: number;
    name: string;
    type: string;
    description?: string;
    units?: string;
    component?: string;
    line_number?: number;
    owner?: string;
    assigned_team_id?: string;
    assigned_team_name?: string;
  }>;
}

export interface BackendDirectoryTreeProps {
  loading?: boolean;
  onNodeClick?: (node: BackendDirectoryNode) => void;
  onPointSelect?: (point: any) => void;
  onPointEdit?: (point: any) => void;
  selectedKeys?: string[];
  expandedKeys?: string[];
  onExpand?: (expandedKeys: string[]) => void;
  onSelect?: (selectedKeys: string[], info: { node: EventDataNode<BackendDirectoryNode> }) => void;
  showStats?: boolean;
  searchable?: boolean;
  height?: number | string;
  rootPath?: string;
  maxDepth?: number;
  teamFilter?: string;
  componentFilter?: string;
  typeFilter?: 'histogram' | 'enum' | 'ukm_event' | 'ukm_metric';
  includeMetrics?: boolean;
}

const BackendDirectoryTree: React.FC<BackendDirectoryTreeProps> = ({
  loading: externalLoading = false,
  onNodeClick,
  onPointSelect,
  onPointEdit,
  selectedKeys = [],
  expandedKeys = [],
  onExpand,
  onSelect,
  showStats = true,
  searchable = true,
  height = '600px',
  rootPath = '',
  maxDepth = 10,
  teamFilter,
  componentFilter,
  typeFilter,
  includeMetrics = false,
}) => {
  const [searchTerm, setSearchTerm] = useState('');
  const [highlightedKeys, setHighlightedKeys] = useState<string[]>([]);
  const [internalExpandedKeys, setInternalExpandedKeys] = useState<string[]>([]);
  const [loading, setLoading] = useState(false);
  const [backendData, setBackendData] = useState<any>(null);
  const [error, setError] = useState<string | null>(null);

  // Load directory tree data from backend
  const loadDirectoryTree = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const response = await directoryApi.getDirectoryTree({
        root_path: rootPath,
        max_depth: maxDepth,
        include_metrics: includeMetrics,
        team_filter: teamFilter,
        component_filter: componentFilter,
        type_filter: typeFilter,
      });

      if (response.success && response.data) {
        setBackendData(response);
        console.log('🌳 [BackendDirectoryTree] Directory tree loaded:', {
          totalMetrics: response.total_metrics,
          directories: response.stats.total_directories,
          files: response.stats.total_files,
        });
      } else {
        setError('Failed to load directory tree');
        console.error('❌ [BackendDirectoryTree] API returned unsuccessful response');
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unknown error occurred');
      console.error('❌ [BackendDirectoryTree] Error loading directory tree:', err);
    } finally {
      setLoading(false);
    }
  }, [rootPath, maxDepth, includeMetrics, teamFilter, componentFilter, typeFilter]);

  // Load data on mount and when filters change
  useEffect(() => {
    loadDirectoryTree();
  }, [loadDirectoryTree]);

  // Search functionality
  const searchInTree = useCallback((node: BackendDirectoryNode, term: string): boolean => {
    const lowerTerm = term.toLowerCase();

    // Check if current node matches
    if (node.name.toLowerCase().includes(lowerTerm)) {
      return true;
    }

    // Check if any component matches
    if (node.components.some(comp => comp.toLowerCase().includes(lowerTerm))) {
      return true;
    }

    // Check if any team matches
    if (node.assigned_teams.some(team => team.toLowerCase().includes(lowerTerm))) {
      return true;
    }

    // Check if any metric matches (if metrics are included)
    if (node.metrics) {
      if (node.metrics.some(metric =>
        metric.name.toLowerCase().includes(lowerTerm) ||
        (metric.description && metric.description.toLowerCase().includes(lowerTerm))
      )) {
        return true;
      }
    }

    // Recursively search children
    if (node.children) {
      return node.children.some(child => searchInTree(child, term));
    }

    return false;
  }, []);

  // Find all nodes that match search term
  const findMatchingKeys = useCallback((node: BackendDirectoryNode, term: string, matches: string[] = []): string[] => {
    if (searchInTree(node, term)) {
      matches.push(node.path);
    }

    // Add all parent paths to ensure expanded tree shows matches
    if (node.children) {
      node.children.forEach(child => {
        const childMatches = findMatchingKeys(child, term, matches);
        if (childMatches.length > 0) {
          matches.push(node.path); // Add parent path if child matches
        }
      });
    }

    return matches;
  }, [searchInTree]);

  // Handle search
  useEffect(() => {
    if (searchTerm.trim() && backendData?.data) {
      const matches = findMatchingKeys(backendData.data, searchTerm.trim());
      setHighlightedKeys(matches);

      // Auto-expand parent nodes of matches
      const expandKeys = new Set<string>();
      const addParentPaths = (node: BackendDirectoryNode, targetPath: string) => {
        if (node.path === targetPath || (node.children && node.children.some(child =>
          child.path === targetPath || addParentPaths(child, targetPath)
        ))) {
          // Find parent path
          const parts = node.path.split('/');
          parts.pop(); // Remove current node
          if (parts.length > 0) {
            expandKeys.add(parts.join('/'));
          }
          return true;
        }
        return false;
      };

      matches.forEach(matchPath => {
        if (backendData.data) {
          addParentPaths(backendData.data, matchPath);
        }
      });

      if (onExpand && expandKeys.size > 0) {
        onExpand(Array.from(expandKeys));
      }
    } else {
      setHighlightedKeys([]);
    }
  }, [searchTerm, backendData, findMatchingKeys, onExpand]);

  // Convert backend node to Ant Design Tree format (memoized static structure)
  const convertToTreeData = useCallback((node: BackendDirectoryNode): DataNode => {
    const nodeTitle = (
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          padding: '2px 0',
          borderRadius: '4px',
        }}
        onClick={() => onNodeClick?.(node)}
      >
        <Space size="small">
          {node.type === 'file' ? (
            <FileOutlined style={{ color: '#1890ff' }} />
          ) : (
            <FolderOutlined style={{ color: '#faad14' }} />
          )}
          <Text
            style={{
              cursor: 'pointer',
            }}
          >
            {node.name}
          </Text>
          {node.metric_count > 0 && (
            <Tag color="blue">
              {node.metric_count}
            </Tag>
          )}
        </Space>

        {showStats && node.metric_count > 0 && (
          <Space size="small" onClick={(e) => e.stopPropagation()}>
            <Badge count={node.metric_count} showZero color="#1890ff" />
            {node.file_count > 0 && (
              <Tooltip title="文件数量">
                <Badge count={node.file_count} showZero color="#52c41a" />
              </Tooltip>
            )}
          </Space>
        )}
      </div>
    );

    const treeNode: DataNode = {
      title: nodeTitle,
      key: node.path,
      isLeaf: node.type === 'file',
      children: node.children?.map(child => convertToTreeData(child)),
    };

    return treeNode;
  }, [showStats, onNodeClick]);

  // Update tree data when backend data changes - static structure only
  const treeData = useMemo(() => {
    if (backendData?.data) {
      return [convertToTreeData(backendData.data)];
    } else {
      return [];
    }
  }, [backendData, convertToTreeData]);

  // Handle node selection
  const handleSelect = useCallback((
    selectedKeys: any[],
    info: { node: EventDataNode<BackendDirectoryNode>; selected: boolean; selectedNodes: BackendDirectoryNode[] }
  ) => {
    const { node, selectedNodes } = info;

    // If it's a file node with metrics
    if (node.isLeaf && selectedNodes.length > 0) {
      const selectedNode = selectedNodes[0];
      if (selectedNode.metrics && selectedNode.metrics.length > 0) {
        // For now, select the first metric. Could be enhanced to show multiple metrics
        onPointSelect?.(selectedNode.metrics[0]);
      }
    }

    onSelect?.(selectedKeys as string[], info as any);
  }, [onPointSelect, onSelect]);

  // Handle node expansion
  const handleExpand = useCallback((expandedKeys: any[], info: any) => {
    console.log('🌳 [BackendDirectoryTree] Tree expansion triggered:', {
      expandedKeys,
      info,
      nodeKey: info.node?.key,
      expanded: info.expanded
    });
    setInternalExpandedKeys(expandedKeys as string[]);
    onExpand?.(expandedKeys as string[]);
  }, [onExpand]);

  // Right click menu
  const handleRightClick = useCallback(({ node }: { node: any }) => {
    const handleMenuClick = ({ key }: { key: string }) => {
      switch (key) {
        case 'view':
          onNodeClick?.(node);
          break;
        case 'expand':
          if (node.children) {
            const keysToExpand = [node.key];
            const expandAllChildren = (children: any[]) => {
              children.forEach((child: any) => {
                keysToExpand.push(child.key);
                if (child.children) {
                  expandAllChildren(child.children);
                }
              });
            };
            expandAllChildren(node.children);
            onExpand?.(Array.from(new Set([...expandedKeys, ...keysToExpand])));
          }
          break;
        case 'collapse':
          if (node.children) {
            const keysToCollapse = [node.key];
            const collapseAllChildren = (children: any[]) => {
              children.forEach((child: any) => {
                keysToCollapse.push(child.key);
                if (child.children) {
                  collapseAllChildren(child.children);
                }
              });
            };
            collapseAllChildren(node.children);
            const newExpandedKeys = expandedKeys.filter(key => !keysToCollapse.includes(key));
            onExpand?.(newExpandedKeys);
          }
          break;
        default:
          break;
      }
    };

    const contextMenu = (
      <Menu onClick={handleMenuClick}>
        <Menu.Item key="view" icon={<EyeOutlined />}>
          查看详情
        </Menu.Item>
        {node.children && (
          <>
            <Menu.Item key="expand" icon={<DownOutlined />}>
              展开所有子节点
            </Menu.Item>
            <Menu.Item key="collapse" icon={<RightOutlined />}>
              折叠所有子节点
            </Menu.Item>
          </>
        )}
      </Menu>
    );

    console.log('Right click on node:', node);
  }, [expandedKeys, onExpand, onNodeClick]);

  // Batch operations menu
  const batchActionsMenu = (
    <Menu>
      <Menu.Item key="expandAll" icon={<DownOutlined />}>
        展开所有节点
      </Menu.Item>
      <Menu.Item key="collapseAll" icon={<RightOutlined />}>
        折叠所有节点
      </Menu.Item>
      <Menu.Divider />
      <Menu.Item key="expandFirstLevel" icon={<FolderOpenOutlined />}>
        展开第一级
      </Menu.Item>
    </Menu>
  );

  // Show loading state
  if (loading || externalLoading) {
    return (
      <div style={{ height, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
        <Spin size="large" />
      </div>
    );
  }

  // Show error state
  if (error) {
    return (
      <div style={{ height, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center' }}>
        <Text type="danger">加载目录树失败</Text>
        <Text type="secondary">{error}</Text>
        <Button type="primary" onClick={loadDirectoryTree} style={{ marginTop: 16 }}>
          重试
        </Button>
      </div>
    );
  }

  return (
    <div style={{ height, display: 'flex', flexDirection: 'column' }}>
      {/* Toolbar */}
      <div style={{ marginBottom: '16px', display: 'flex', gap: '8px', alignItems: 'center' }}>
        {searchable && (
          <Search
            placeholder="搜索目录或遥测点..."
            allowClear
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
            style={{ flex: 1 }}
            prefix={<SearchOutlined />}
          />
        )}
        <Dropdown overlay={batchActionsMenu} trigger={['click']}>
          <Button icon={<FilterOutlined />}>
            批量操作 <DownOutlined />
          </Button>
        </Dropdown>
      </div>

      {/* Statistics */}
      {showStats && backendData?.stats && (
        <div style={{ marginBottom: '16px', padding: '12px', backgroundColor: '#fafafa', borderRadius: '6px' }}>
          <Space size="large">
            <div>
              <Text type="secondary">总目录</Text>
              <div style={{ fontSize: '18px', fontWeight: 'bold', color: '#1890ff' }}>
                {backendData.stats.total_directories}
              </div>
            </div>
            <div>
              <Text type="secondary">总文件</Text>
              <div style={{ fontSize: '18px', fontWeight: 'bold', color: '#52c41a' }}>
                {backendData.stats.total_files}
              </div>
            </div>
            <div>
              <Text type="secondary">总遥测点</Text>
              <div style={{ fontSize: '18px', fontWeight: 'bold', color: '#faad14' }}>
                {backendData.total_metrics}
              </div>
            </div>
          </Space>
        </div>
      )}

      {/* Tree component */}
      <div style={{ flex: 1, overflow: 'auto' }}>
        {treeData.length > 0 ? (
          <Tree
            showLine
            showIcon={false}
            blockNode
            treeData={treeData as any[]}
            selectedKeys={selectedKeys as any[]}
            expandedKeys={internalExpandedKeys as any[]}
            onExpand={handleExpand}
            onSelect={handleSelect}
            onRightClick={handleRightClick}
            virtual
            height={typeof height === 'number' ? height - 120 : undefined}
          />
        ) : (
          <div style={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            height: typeof height === 'number' ? height - 120 : '400px',
            flexDirection: 'column'
          }}>
            <Text type="secondary">暂无目录数据</Text>
            <Button type="link" onClick={loadDirectoryTree}>
              刷新
            </Button>
          </div>
        )}
      </div>

      {/* Search results indicator */}
      {searchTerm && highlightedKeys.length > 0 && (
        <div style={{ marginTop: '8px', padding: '8px', backgroundColor: '#e6f7ff', borderRadius: '4px' }}>
          <Text type="secondary">
            找到 {highlightedKeys.length} 个匹配结果
          </Text>
        </div>
      )}
    </div>
  );
};

export default BackendDirectoryTree;